package main

import (
	"crypto/md5"
	"database/sql"
	"fmt"
	"time"
)

type User struct {
	Ind int64          `db:"ind"`
	Key sql.NullString `db:"subscription_key"`
}
type Token struct {
	Ind      int64          `db:"ind"`
	Token    sql.NullString `db:"token"`
	User_key sql.NullString `db:"user_key"`
	Sign     int            `db:"sign"`
}

func main() {
	dsn := fmt.Sprintf("%s:%s@%s(%s:%d)/%s", USERNAME, PASSWORD, NETWORK, SERVER, PORT, DATABASE)
	DB, err := sql.Open("mysql", dsn)
	defer DB.Close()
	if err != nil {
		fmt.Printf("Open mysql failed,err:%v\n", err)
		return
	}
	DB.SetConnMaxLifetime(100 * time.Second) //最大连接周期，超过时间的连接就close
	DB.SetMaxOpenConns(100)                  //设置最大连接数
	DB.SetMaxIdleConns(16)                   //设置闲置连接数
	tx, err := DB.Begin()
	key := "fc700fc2c8914dc796720f2a4f9553a6"
	if VertKey(key, tx) {
		token := MakeToken(key, "synthesis")
		var tok = Token{Token: sql.NullString{token, true}, User_key: sql.NullString{key, true}, Sign: 0}
		InsertToken(tok, DB)
	}
	tx.Commit()
}

/*
user 私钥发过去，身份认证，做个token给他，记录token，
token和报文发过来，验证token
*/
//验证私钥
func VertKey(str string, DB *sql.Tx) (sig bool) {
	row := DB.QueryRow("select count(*) from hy_tts_user where subscription_key = ?", str)
	var num int
	row.Scan(&num)
	sig = false
	if num > 0 {
		sig = true
	}
	return
}

//插入token数据
func InsertToken(token Token, DB *sql.DB) (err error) {
	tx, err := DB.Begin()
	stmt, _ := DB.Prepare("insert INTO hy_tts_token(token,user_key,sign) values(?,?,?)")
	defer stmt.Close()
	result, err := stmt.Exec(token.Token, token.User_key, token.Sign)
	//result,err := DB.Exec("insert INTO hy_tts_log(err_msg) values(?)","YDZ")
	if err != nil {
		tx.Rollback()
		fmt.Printf("Insert failed,err:%v", err)
		return
	}
	lastInsertID, err := result.LastInsertId()
	if err != nil {
		tx.Rollback()
		fmt.Printf("Get lastInsertID failed,err:%v", err)
		return
	}
	fmt.Println("LastInsertID:", lastInsertID)
	rowsaffected, err := result.RowsAffected()
	if err != nil {
		tx.Rollback()
		fmt.Printf("Get RowsAffected failed,err:%v", err)
		return
	}
	fmt.Println("RowsAffected:", rowsaffected)
	tx.Commit()
	return
}

//生成token
func MakeToken(key string, meth string) (res string) {
	time := time.Now()
	//'模块名' + '控制器名' + '方法名' + '2013-12-18' + '加密密钥'
	str := "huiyan.com" + meth + time.Format(timeTemple) + meth
	res = md5V2(str)
	return
}

//md5生成
func md5V2(str string) string {
	data := []byte(str)
	has := md5.Sum(data)
	md5str := fmt.Sprintf("%x", has)
	return md5str
}
